#ifndef ENGAGEMENTRULES_H
#define ENGAGEMENTRULES_H

#include <iostream>
#include <vector>
#include <utility>
#include "point.h"

using namespace std;

enum PieceType
{
    King,
    Advisor,
    Elephant,
    Horse,
    Chariot,
    Cannon,
    Pawn
};

enum PieceColor
{
    Red,
    Black
};

class ChessPiece
{
public:
    ChessPiece(PieceType t, PieceColor c, int x, int y):type(t), color(c), position(x, y)
    {
    }
    PieceType getType() const
    {
        return type;
    }

    PieceColor getPieceColor() const
    {
        return color;
    }

    Point getPosition() const
    {
        return position;
    }

    void setPosition(int x, int y)
    {
        position = Point(x, y);
    }

    virtual bool canMoveTo(const Point& target, const vector<vector<ChessPiece*> >& board) const= 0;
    virtual ~ChessPiece()
    {
    }

private:
    PieceType type;
    PieceColor color;
    Point position;
};

// 各种棋子类的声明
class KingPiece : public ChessPiece
{
public:
    KingPiece(PieceColor c, int x, int y);
    bool canMoveTo(const Point& target, const vector<vector<ChessPiece*> >& board) const;
};

class AdvisorPiece : public ChessPiece
{
public:
    AdvisorPiece(PieceColor c, int x, int y);
    bool canMoveTo(const Point& target, const vector<vector<ChessPiece*> >& board) const;
};

class ElephantPiece : public ChessPiece
{
public:
    ElephantPiece(PieceColor c, int x, int y);
    bool canMoveTo(const Point& target, const vector<vector<ChessPiece*> >& board) const;
};

class HorsePiece : public ChessPiece
{
public:
    HorsePiece(PieceColor c, int x, int y);
    bool canMoveTo(const Point& target, const vector<vector<ChessPiece*> >& board) const;
};

class ChariotPiece : public ChessPiece
{
public:
    ChariotPiece(PieceColor c, int x, int y);
    bool canMoveTo(const Point& target, const vector<vector<ChessPiece*> >& board) const;
};

class CannonPiece : public ChessPiece
{
public:
    CannonPiece(PieceColor c, int x, int y);
    bool canMoveTo(const Point& target, const vector<vector<ChessPiece*> >& board) const;
};

class PawnPiece : public ChessPiece
{
public:
    PawnPiece(PieceColor c, int x, int y);
    bool canMoveTo(const Point& target, const vector<vector<ChessPiece*> >& board) const;
};

// 工厂类声明
class ChessPieceFactory
{
public:
    static ChessPiece* createPiece(PieceType type, PieceColor color, int x, int y);
};

#endif